import {
  PerspectiveCamera,
  Scene,
  WebGLRenderer,
  Mesh,
  BoxBufferGeometry,
  MeshBasicMaterial,
  TextureLoader,
  AmbientLight,
  AxesHelper,
  GridHelper,
  PlaneBufferGeometry,
  DoubleSide,
  Color,
  MeshPhysicalMaterial,
  PointLight,
  PMREMGenerator,
  PlaneGeometry,
} from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import Stats from "three/examples/jsm/libs/stats.module";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
import { RoomEnvironment } from "three/examples/jsm/environments/RoomEnvironment";

let camera: PerspectiveCamera, scene: Scene, renderer: WebGLRenderer;
let control: OrbitControls;
let stats: Stats;
let mesh: Mesh;
let wheels: Array<Mesh> = [];

init();
animate();

function init() {
  camera = new PerspectiveCamera(
    70,
    window.innerWidth / window.innerHeight,
    1,
    1000
  );
  camera.position.set(5, 5, 5);

  scene = new Scene();
  scene.background = new Color("#eee");

  //   add lights
  let ambientLight = new AmbientLight("#fff", 0.1);
  scene.add(ambientLight);
  // let pointLight = new PointLight("#fff", 1)
  // pointLight.position.set(0, 300, 0);
  // scene.add(pointLight)

  //   add axes
  let axes = new AxesHelper(100);
  scene.add(axes);

  // add grid
  let grid = new GridHelper(100, 40, "#bbb", "#bbb");
  scene.add(grid);
  let plane = new PlaneGeometry(20, 20);
  let planeMesh = new Mesh(
    plane,
    new MeshBasicMaterial({
      color: "#fff",
    })
  );
  planeMesh.rotateX(-Math.PI / 2);
  planeMesh.receiveShadow = true;
  scene.add(planeMesh);

  // load modal
  let dracoLoader = new DRACOLoader();
  dracoLoader.setDecoderPath("./static/js/gltf/");

  let bodyMaterial = new MeshPhysicalMaterial({
    color: 0xff0000,
    metalness: 0.6,
    roughness: 0.4,
    clearcoat: 0.05,
    clearcoatRoughness: 0.05,
  });
  let glassMaterial = new MeshPhysicalMaterial({
    color: 0xffffff,
    metalness: 0,
    roughness: 0.1,
    transmission: 0.9,
    transparent: true,
  });

  // 颜色控件
  let input1 = document.createElement('input');
  input1.type = 'color';
  input1.style.zIndex = '10';
  input1.style.position = 'absolute';
  input1.style.right = '20px';
  input1.style.top = '100px';
  input1.addEventListener('input', () => {
    bodyMaterial.color.set(input1.value)
  })
  document.body.appendChild(input1)

  let loader = new GLTFLoader();
  loader.setDRACOLoader(dracoLoader);
  loader.load(require("../static/modal/ferrari.glb").default, (data) => {
    console.log(data);
    let carModel = data.scene.children[0];
    carModel.castShadow = true;

    (carModel.getObjectByName("body") as Mesh).material = bodyMaterial;
    (carModel.getObjectByName("glass") as Mesh).material = glassMaterial;

    wheels.push(
      carModel.getObjectByName("wheel_fl") as Mesh,
      carModel.getObjectByName("wheel_fr") as Mesh,
      carModel.getObjectByName("wheel_rl") as Mesh,
      carModel.getObjectByName("wheel_rr") as Mesh
    );
    scene.add(carModel);
  });

  renderer = new WebGLRenderer({ antialias: true });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

  control = new OrbitControls(camera, renderer.domElement);
  stats = Stats();
  document.body.appendChild(stats.domElement);
  let roomEnvironment = new RoomEnvironment();
  let pmremGenerator = new PMREMGenerator(renderer);
  scene.environment = pmremGenerator.fromScene(roomEnvironment).texture;
}

function animate() {
  requestAnimationFrame(animate);

  for (let i = 0; i < wheels.length; i++) {
    wheels[i].rotation.x = (-performance.now() / 1000) * Math.PI;
  }

  stats.update();
  renderer.render(scene, camera);
}
